package com.purchase.service.impl;

import com.purchase.entity.Cart;
import com.purchase.entity.Coupon;
import com.purchase.entity.GoodsStock;
import com.purchase.mapper.CartMapper;
import com.purchase.mapper.CouponMapper;
import com.purchase.mapper.GoodsStockMapper;
import com.purchase.service.CartService;
import com.purchase.util.LogInfo;
import com.purchase.util.RequestForm;
import com.purchase.util.ResponseForm;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import java.math.BigDecimal;
import java.util.*;

import static java.util.stream.Collectors.groupingBy;

@Slf4j
@Service
public class CartServiceImpl implements CartService {

    @Autowired
    private CartMapper cartMapper;

    @Autowired
    private GoodsStockMapper goodsStockMapper;

    @Autowired
    private CouponMapper couponMapper;

    @Override
    public ResponseForm getCart(RequestForm param) {
        ResponseForm result = new ResponseForm();
        Map<String, Object> paramMap = (Map<String, Object>) param.getData();
        try {
            String wxUid = (String) paramMap.get("wxUid");
            String storeNo = (String) paramMap.get("storeNo");
            if (!StringUtils.isNotBlank(storeNo) || !StringUtils.isNotBlank(wxUid)) {
                result.setStatus(false);
                result.setMessage(LogInfo.PARAM_ERROR);
                log.error(LogInfo.PARAM_ERROR);
                return result;
            }

            //数据库中获取购物车列表
            List<Cart> list = cartMapper.getCartByWxUidAndStoreNo(paramMap);

            List<Object> resultList = new ArrayList<>();
            //按 活动ID 分组
            Map<Integer, List<Cart>> collectById = list.parallelStream()
                    .collect(groupingBy(Cart::getActivityId));
            //遍历 collectById，以取到 first 里的活动名称、活动时间、活动有效标识，活动ID 和商品列表
            collectById.forEach((k, v) -> {
                Map<String, Object> mapById = new HashMap<>();
                Date activityEndTime = v.get(0).getActivityEndTime();
                String activityName = v.get(0).getActivityName();
                Integer activityStatus = v.get(0).getActivityStatus();
                mapById.put("activityEndTime", activityEndTime);
                mapById.put("activityName", activityName);
                mapById.put("activityStatus", activityStatus);
                mapById.put("activityId", k);
                mapById.put("list", v);
                //加入本活动有效优惠券
                List<Coupon> couponList = couponMapper.getReceiveList(mapById);
                if (couponList.size() > 0) {
                    mapById.put("couponFlag", 1);
                } else {
                    mapById.put("couponFlag", 0);
                }
                resultList.add(mapById);
            });

            result.setData(resultList);
        } catch (Exception e) {
            result.setStatus(false);
            result.setMessage(LogInfo.ERROR);
            log.error("获取购物车error", e);
        }
        return result;
    }

    @Override
    public ResponseForm insertOrUpdateGoodsToCart(RequestForm param) {
        ResponseForm result = new ResponseForm();
        Map<String, Object> paramMap = (Map<String, Object>) param.getData();
        try {
            String wxUid = (String) paramMap.get("wxUid");
            String storeNo = (String) paramMap.get("storeNo");
            String goodsId = (String) paramMap.get("goodsId");
            String goodsNum = (String) paramMap.get("goodsNum");
            String goodsPrice = (String) paramMap.get("goodsPrice");
            String specsName = (String) paramMap.get("specsName");
            String goodsPic = (String) paramMap.get("goodsPic");
            String goodsName = (String) paramMap.get("goodsName");
            String goodsColor = (String) paramMap.get("goodsColor");
            String originalPrice = (String) paramMap.get("originalPrice");
            String activityId = (String) paramMap.get("activityId");
            if (!StringUtils.isNotBlank(wxUid)
                    || !StringUtils.isNotBlank(storeNo)
                    || !StringUtils.isNotBlank(goodsId)
                    || !StringUtils.isNotBlank(goodsNum)
                    || !StringUtils.isNotBlank(goodsPrice)
                    || !StringUtils.isNotBlank(specsName)
                    || !StringUtils.isNotBlank(goodsName)
                    || !StringUtils.isNotBlank(goodsColor)
                    || !StringUtils.isNotBlank(originalPrice)
                    || !StringUtils.isNotBlank(goodsPic)
                    || !StringUtils.isNotBlank(activityId)) {
                result.setStatus(false);
                result.setMessage(LogInfo.PARAM_ERROR);
                log.error(LogInfo.PARAM_ERROR);
                return result;
            }

            //校验库存
            GoodsStock goodsStock = new GoodsStock();
            goodsStock.setGoodsId(Integer.valueOf(goodsId));
            goodsStock.setSpecsName(specsName);
            List<GoodsStock> goodsStocks = goodsStockMapper.select(goodsStock);
            if (goodsStocks.size() < 1) {
                result.setStatus(false);
                result.setMessage("库存错误");
                log.error("购物车校验库存error");
                return result;
            }

            Map<String, Object> goodsInCart = cartMapper.getGoodsInCart(paramMap);
            if (goodsInCart != null) {
                goodsNum = String.valueOf(Integer.parseInt(String.valueOf(goodsInCart.get("goods_num"))) + Integer.parseInt(goodsNum));
                paramMap.put("goodsNum", goodsNum);
            }
            cartMapper.insertOrUpdateGoodsToCart(paramMap);
        } catch (Exception e) {
            result.setStatus(false);
            result.setMessage(LogInfo.ERROR);
            log.error("添加商品进购物车error", e);
        }
        return result;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public ResponseForm modifyGoodsInCart(RequestForm param) {
        ResponseForm result = new ResponseForm();
        Map<String, Object> paramMap = (Map<String, Object>) param.getData();
        try {
            String wxUid = (String) paramMap.get("wxUid");
            String storeNo = (String) paramMap.get("storeNo");
            String goodsId = (String) paramMap.get("goodsId");
            String goodsNum = (String) paramMap.get("goodsNum");
            String goodsPrice = (String) paramMap.get("goodsPrice");
            String originalPrice = (String) paramMap.get("originalPrice");
            String specsName = (String) paramMap.get("specsName");
            String goodsPic = (String) paramMap.get("goodsPic");
            String goodsName = (String) paramMap.get("goodsName");
            String goodsColor = (String) paramMap.get("goodsColor");
            String oldGoodsId = (String) paramMap.get("oldGoodsId");
            String oldSpecsName = (String) paramMap.get("oldSpecsName");
            if (!StringUtils.isNotBlank(wxUid)
                    || !StringUtils.isNotBlank(storeNo)
                    || !StringUtils.isNotBlank(goodsId)
                    || !StringUtils.isNotBlank(goodsNum)
                    || !StringUtils.isNotBlank(goodsPrice)
                    || !StringUtils.isNotBlank(originalPrice)
                    || !StringUtils.isNotBlank(specsName)
                    || !StringUtils.isNotBlank(goodsName)
                    || !StringUtils.isNotBlank(goodsColor)
                    || !StringUtils.isNotBlank(goodsPic)
                    || !StringUtils.isNotBlank(oldGoodsId)
                    || !StringUtils.isNotBlank(oldSpecsName)) {
                result.setStatus(false);
                result.setMessage(LogInfo.PARAM_ERROR);
                log.error(LogInfo.PARAM_ERROR);
                return result;
            }


            if (oldGoodsId.equals(goodsId) && oldSpecsName.equals(specsName)) {
                //如果则只修改数量
                cartMapper.updateOldGoodsInCart(paramMap);
            } else {
                Map<String, Object> newCartDetail = cartMapper.getCartByPrimaryKeys(paramMap);
                Map<String, Object> oldCartMap = new HashMap<>(paramMap);
                oldCartMap.put("specsName", oldSpecsName);
                Map<String, Object> oldCartDetail = cartMapper.getCartByPrimaryKeys(oldCartMap);

                //如果把购物车的商品A换为新商品B且B不存在购物车内
                if (newCartDetail == null) {
                    //如果购物车中A的数量小于等于要换的数量，则新建B，并删除A
                    paramMap.put("goodsNum", Integer.parseInt(goodsNum));
                    cartMapper.insertOrUpdateGoodsToCart(paramMap);
                    paramMap.put("goodsId", oldGoodsId);
                    paramMap.put("specsName", oldSpecsName);
                    cartMapper.bakCarts(paramMap);
                    cartMapper.deleteCart(paramMap);
                }

                //如果把购物车的商品A换为新商品B且B已存在购物车内
                if (newCartDetail != null) {
                    //如果购物车中A的数量大于要换的数量，则更新A和B的数量
                    if (Integer.parseInt(String.valueOf(oldCartDetail.get("goodsNum"))) > Integer.parseInt(goodsNum)) {
                        paramMap.put("goodsNum", (int) newCartDetail.get("goodsNum") + Integer.parseInt(goodsNum));
                        oldCartMap.put("goodsNum", Integer.parseInt(String.valueOf(oldCartDetail.get("goodsNum"))) - Integer.parseInt(goodsNum));
                        cartMapper.updateGoodsInCart(paramMap);
                        cartMapper.updateGoodsInCart(oldCartMap);
                    } else {
                        //如果购物车中A的数量小于等于要换的数量，则删除A并更新B的数量和价格
                        paramMap.put("goodsId", oldGoodsId);
                        paramMap.put("specsName", oldSpecsName);
                        cartMapper.bakCarts(paramMap);
                        cartMapper.deleteCart(paramMap);
                        int newGoodsNum = (int) newCartDetail.get("goodsNum") + Integer.valueOf(goodsNum);
                        BigDecimal newGoodsPrice = new BigDecimal(goodsPrice);
                        paramMap.put("goodsNum", newGoodsNum);
                        paramMap.put("goodsPrice", newGoodsPrice);
                        paramMap.put("originalPrice", originalPrice);
                        paramMap.put("goodsId", goodsId);
                        paramMap.put("specsName", specsName);
                        cartMapper.updateGoodsInCart(paramMap);
                    }
                }
            }

        } catch (Exception e) {
            result.setStatus(false);
            result.setMessage(LogInfo.ERROR);
            log.error("修改购物车商品属性error", e);
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        }
        return result;
    }

    @Override
    public ResponseForm removeGoodsInCart(RequestForm param) {
        ResponseForm result = new ResponseForm();
        Map<String, Object> paramMap = (Map<String, Object>) param.getData();
        try {
            String wxUid = (String) paramMap.get("wxUid");
            String storeNo = (String) paramMap.get("storeNo");
            String goodsId = (String) paramMap.get("goodsId");
            String specsName = (String) paramMap.get("specsName");
            if (!StringUtils.isNotBlank(storeNo)
                    || !StringUtils.isNotBlank(wxUid)
                    || !StringUtils.isNotBlank(goodsId)
                    || !StringUtils.isNotBlank(specsName)) {
                result.setStatus(false);
                result.setMessage(LogInfo.PARAM_ERROR);
                log.error(LogInfo.PARAM_ERROR);
                return result;
            }

            cartMapper.bakCarts(paramMap);
            cartMapper.deleteCart(paramMap);
        } catch (Exception e) {
            result.setStatus(false);
            result.setMessage(LogInfo.ERROR);
            log.error("删除购物车内商品error", e);
        }
        return result;
    }

    @Override
    public ResponseForm emptyCart(RequestForm param) {
        ResponseForm result = new ResponseForm();
        Map<String, Object> paramMap = (Map<String, Object>) param.getData();
        try {
            String wxUid = (String) paramMap.get("wxUid");
            String storeNo = (String) paramMap.get("storeNo");
            if (!StringUtils.isNotBlank(storeNo) || !StringUtils.isNotBlank(wxUid)) {
                result.setStatus(false);
                result.setMessage(LogInfo.PARAM_ERROR);
                log.error(LogInfo.PARAM_ERROR);
                return result;
            }

            cartMapper.bakCarts(paramMap);
            cartMapper.deleteCart(paramMap);
        } catch (Exception e) {
            result.setStatus(false);
            result.setMessage(LogInfo.ERROR);
            log.error("清空购物车error", e);
        }
        return result;
    }

}
